package handler

import (
	"context"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/golang/protobuf/ptypes/wrappers"
	moneyC "kop/modules/money/client"
	"time"

	"kop/framework/errors"
	"kop/libs/database"
	"kop/modules/building/configuration"
	"kop/modules/building/entity"
	"kop/modules/building/models"
	"kop/pb"
	"kop/util/rand"

	itemC "kop/modules/item/client"
	roleC "kop/modules/role/client"
)

func (h *BuildingServiceHandler) GetDispatch(ctx context.Context, _ *empty.Empty, resp *pb.DispatchList) error {

	var roleID = h.GetRoleID(ctx)

	var c int
	database.DB.Table(entity.Building{}.TableName()).Where("role_id = ?", roleID).Count(&c)

	if c > 1 {

		var role = roleC.GetRole(roleID)

		var data = models.GetDispatchList(roleID)

		var m = make(map[int32]entity.Dispatch, len(data))
		for _, v := range data {

			if time.Now().Sub(v.CreatedAt).Seconds() > 3600*6 {
				_ = models.DelDispatch(v)
			} else {
				m[v.DispatchID] = v
			}
		}

		data = make([]entity.Dispatch, 0, len(m))
		for _, v := range m {
			data = append(data, v)
		}

		// 任务数量 = 船数量
		var n = c - 1
		n = n - len(data)
		if n > 0 {

			var configs = make([]rand.Value, 0, len(configuration.DispatchConfigs))
			for _, v := range configuration.DispatchConfigs {
				if _, ok := m[v.ID]; !ok {
					configs = append(configs, v)
				}
			}

			configs = rand.WithWeight(configs, n)
			for _, v := range configs {
				data = append(data, models.CreateDispatch(roleID, v.GetID(), role.Level))
			}
		}

		resp.List = make([]*pb.Dispatch, 0, len(data))
		for _, v := range data {
			resp.List = append(resp.List, buildPbDispatch(v, role.Level))
		}
	}

	return nil
}

func (h *BuildingServiceHandler) Dispatch(ctx context.Context, req *pb.DispatchRequest, resp *pb.Dispatch) error {

	var roleID = h.GetRoleID(ctx)

	var data *entity.Dispatch
	var list = models.GetDispatchList(roleID)

	for _, v := range list {
		if v.ShipID == req.ShipID {
			return errors.ParamError
		}

		if v.DispatchID == req.DispatchID {

			var Copy = v
			data = &Copy
		}
	}

	if data == nil {
		return errors.ParamError
	}

	var peerage = roleC.GetRole(roleID).Level
	var conf2 = configuration.GetDispatchCostByPeerage(peerage)

	if err := moneyC.AsyncSubCoin(ctx, conf2.CostCoin); err != nil {
		return err
	}

	data.ShipID = req.ShipID
	data.Peerage = peerage
	_ = models.SaveDispatch(data)

	*resp = *buildPbDispatch(*data, 0)
	return nil
}

func (h *BuildingServiceHandler) FinishDispatch(ctx context.Context, req *wrappers.Int32Value, resp *pb.RawItem) error {

	var roleID = h.GetRoleID(ctx)

	var conf = configuration.GetDispatch(req.Value)

	var data = models.GetDispatch(roleID, req.Value)
	if data.ShipID == 0 {
		return errors.ParamError
	}

	var sec = data.GetTime()
	if sec > 0 {
		return errors.ParamError
	}

	_ = models.DelDispatch(data)

	*resp = *itemByDispatchID(conf, data.Peerage)
	if data.ShipID == conf.ShipID {
		// 正确的船+20%收益
		resp.Number += int32(float32(resp.Number) * 0.2)
	}

	_ = itemC.AddItem(roleID, resp.ItemID, resp.Number)

	return nil
}

func (h *BuildingServiceHandler) RefreshDispatch(ctx context.Context, req *empty.Empty, resp *pb.DispatchList) error {

	var roleID = h.GetRoleID(ctx)

	if err := itemC.AsyncDelItem(roleID, h.GetServerID(ctx), 101333, 1); err != nil {
		return err
	}

	_ = models.DelDispatchByRoleID(roleID)

	return h.GetDispatch(ctx, req, resp)
}

// peerage 当前角色爵位
func buildPbDispatch(data entity.Dispatch, peerage int32) *pb.Dispatch {

	var conf = configuration.GetDispatch(data.DispatchID)
	var conf2 = configuration.GetDispatchCostByPeerage(peerage)

	var mess = pb.Dispatch{
		ID:     data.DispatchID,
		ShipID: data.ShipID,
		Time:   data.GetTime(),
	}

	if mess.ShipID > 0 {

		mess.Time = data.GetTime()

		peerage = data.Peerage

	} else {
		mess.Coin = int64(conf.CostRate * float64(conf2.CostCoin))
	}

	mess.RawItem = itemByDispatchID(conf, peerage)
	return &mess
}

// 根据任务ID 爵位取道具奖励配置
func itemByDispatchID(conf configuration.DispatchConf, peerage int32) *pb.RawItem {

	var mess pb.RawItem
	mess.ItemID = conf.ItemID

	if conf.ItemNumber > 0 {
		mess.Number = conf.ItemNumber
		return &mess
	}

	var conf2 = configuration.GetDispatchCostByPeerage(peerage)

	var m = conf.ID / 100
	switch m {
	case 1:
		mess.Number = conf2.Reward1
	case 2:
		mess.Number = conf2.Reward2
	case 3:
		mess.Number = conf2.Reward3

	default:
		panic("DispatchConf item num error")
	}

	return &mess
}
